package ar.uba.fi.celdas.util;

import java.util.ResourceBundle;

//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;

import ar.fi.uba.celdas.interfaces.bc.IBaseConocimientos;
import ar.fi.uba.celdas.interfaces.planificacion.IPlanificacion;

public class Instanciador {

	//private static Log log = LogFactory.getLog(Instanciador.class);
	private static Instanciador instance = new Instanciador();
	private static ResourceBundle properties = ResourceBundle.getBundle("classes");
	
	private Instanciador() {}
	
	private <T> T crearInstancia(String nombreProperty, Class<T> interfaze) {
		
		T instancia = null;
		
		if (nombreProperty == null || interfaze == null || !interfaze.isInterface()) {
			throw new IllegalArgumentException("Debe proporcionar un nombre y una interfaz");
		}
		
		if (properties == null) {
			throw new IllegalStateException("Debe existir un archivo classes.properties " +
					"que asocie " + nombreProperty + " con el FQCN de la clase cuya interfaz proporcionó");
		}
		
		if (!properties.containsKey(nombreProperty)) {
			throw new IllegalStateException("El archivo classes.properties " +
					"que asocie " + nombreProperty + " con el FQCN de la clase cuya interfaz proporcionó");
		}
		
		String nombreClase = properties.getString(nombreProperty);
		
		try {
			
			@SuppressWarnings("unchecked")
			Class<T> clazz = (Class<T>) Class.forName(nombreClase);
			
			instancia = clazz.newInstance();
		}
		catch (ClassNotFoundException e) {
			
		//	log.warn("No se encontró la clase " + nombreClase);
		} 
		catch (InstantiationException e) {
			
			//log.warn("No se puede instanciar la clase. Verifique no sea abstracta.");
		} 
		catch (IllegalAccessException e) {

			//log.warn("La clase o el constructor no tienen la visibilidad necesaria.");
		}
		
		return instancia;
	}
	
	public static IBaseConocimientos crearBaseDeConocimiento() {
		
		return instance.crearInstancia("baseconocimiento.classname", IBaseConocimientos.class);
	}
	
	public static IPlanificacion crearPlanificador() {
		
		return instance.crearInstancia("planificador.classname", IPlanificacion.class);
	}
}
